package com.fingard.dsp.bank.directbank.gzelink01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Date;

public class GZELINK01Contract extends GZELINK01Base implements IContract {
    @Override
    public RetAtsContract contract(ReqContract p_req) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req.contractDetail.recAct, "contract");
            if (actItem != null) {
                StringBuilder reqMsg = new StringBuilder();
                if ("01".equals(p_req.contractDetail.step)) {
                    GZELINK01Header bankHeader = new GZELINK01Header();
                    bankHeader.transCode = "311001";
                    bankHeader.reqSeqNo = p_req.contractDetail.askNumber;

                    reqMsg = writeCommonHeader(reqMsg, actItem, bankHeader);
                    boolean limit = getBankConfig().getValueAsBool("useBankMapping");
                    if (limit) {
                        String signMode = getBankConfig().getMapValueByKey("signModeBankMapping", p_req.contractDetail.payBankCode);
                        reqMsg.append("<SIGN_MODE>" + signMode + "</SIGN_MODE>");
                    } else {
                        reqMsg.append("<SIGN_MODE>0</SIGN_MODE>");
                    }
                    reqMsg.append("<SUBMIT_TIME>" + Format.DateTime14Format.format(new Date()) + "</SUBMIT_TIME>");
                    reqMsg.append("<MERCHANT_ID>" + actItem.merchantId + "</MERCHANT_ID>");

                    String bankCode = getBankConfig().getMapValueByKey("BankCodeMapping", p_req.contractDetail.payBankCode);
                    reqMsg.append("<BANK_CODE>" + bankCode + "</BANK_CODE>");
                    reqMsg.append("<ACCOUNT_NO>" + p_req.contractDetail.payAct + "</ACCOUNT_NO>");
                    reqMsg.append("<ACCOUNT_NAME>" + p_req.contractDetail.payName + "</ACCOUNT_NAME>");

                    String cardType = p_req.contractDetail.cardType;
                    if ("3".equals(cardType) || "4".equals(cardType)) {
                        cardType = "02";// 信用卡
                    } else if ("1".equals(cardType)) {
                        cardType = "01";// 存折
                    } else {
                        cardType = "00";// 借记卡(默认)
                    }
                    reqMsg.append("<ACCOUNT_TYPE>" + cardType + "</ACCOUNT_TYPE>");
                    reqMsg.append("<ID_TYPE>" + convertCertTypeToBank(p_req.contractDetail.certType) + "</ID_TYPE>");
                    reqMsg.append("<ID>" + p_req.contractDetail.certNum + "</ID>");
                    reqMsg.append("<TEL>" + p_req.contractDetail.cellPhone + "</TEL>");
                    reqMsg.append("<BUSINESS_CODE>" + "10600" + "</BUSINESS_CODE>");

                    String isPrivate = p_req.contractDetail.isPrivate;
                    if ("1".equals(isPrivate)) {
                        isPrivate = "0";// 私人
                    } else {
                        isPrivate = "1";// 公司
                    }
                    reqMsg.append("<ACCOUNT_PROP>" + isPrivate + "</ACCOUNT_PROP>");
                    reqMsg.append("<LGL_REP_NM>" + p_req.contractDetail.legalName + "</LGL_REP_NM>");
                    reqMsg.append("<LGL_REP_ID_TP>" + convertCertTypeToBank(p_req.contractDetail.legalCertType) + "</LGL_REP_ID_TP>");
                    reqMsg.append("<LGL_REP_ID_NO>" + p_req.contractDetail.legalCertNum + "</LGL_REP_ID_NO>");

                    String deadLine = p_req.contractDetail.deadLine;
                    if (StringHelper.isNullOrEmpty(deadLine)) {
                        deadLine = getBankConfig().getMapValueByKey("contractKeyMapping", "deadLine");
                        if (StringHelper.isNullOrEmpty(deadLine)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "缺失配置节点'deadLine'或值为空!";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                    }

                    String singleLimit = p_req.contractDetail.singleLimit;
                    if (StringHelper.isNullOrEmpty(singleLimit)) {
                        if (getBankConfig().getValueAsBool("singleLimitCut")) {
                            singleLimit = getBankConfig().getMapValueByKey("singleLimitMapping", p_req.contractDetail.payBankCode);
                        } else {
                            singleLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "singleLimit");
                        }

                        if (StringHelper.isNullOrEmpty(singleLimit)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "缺失配置节点'singleLimit'或值为空!";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                    }

                    String periodLimit = p_req.contractDetail.periodLimit;
                    if (StringHelper.isNullOrEmpty(periodLimit)) {
                        periodLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "periodLimit");
                        if (StringHelper.isNullOrEmpty(periodLimit)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "缺失配置节点'periodLimit'或值为空!";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                    }

                    String countLimit = p_req.contractDetail.countLimit;
                    boolean fixCountLimit = getBankConfig().getValueAsBool("fixCountLimit");
                    if (fixCountLimit || StringHelper.isNullOrEmpty(countLimit)) {
                        countLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "countLimit");
                        if (StringHelper.isNullOrEmpty(countLimit)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "缺失配置节点'countLimit'或值为空!";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                    }

                    reqMsg.append("<DISABLE_DATE>" + deadLine + "</DISABLE_DATE>");
                    reqMsg.append("<SINGLE_LIMIT>" + StringHelper.amountMultiply100(singleLimit) + "</SINGLE_LIMIT>");
                    reqMsg.append("<LIMIT_PERIOD_UNIT>0" + periodLimit + "</LIMIT_PERIOD_UNIT>");
                    reqMsg.append("<MAX_CNT_LIMIT>" + countLimit + "</MAX_CNT_LIMIT>");
                    reqMsg.append("</TRANS_SUM>");
                    reqMsg.append("</BODY>");
                    reqMsg.append("</GZELINK>");
                } else if ("02".equals(p_req.contractDetail.step)) {
                    GZELINK01Header bankHeader = new GZELINK01Header();
                    bankHeader.transCode = "311002";
                    bankHeader.reqSeqNo = p_req.reqHeader.transSeqID;

                    reqMsg = writeCommonHeader(reqMsg, actItem, bankHeader);
                    reqMsg.append("<SUBMIT_TIME>" + Format.DateTime14Format.format(new Date()) + "</SUBMIT_TIME>");
                    reqMsg.append("<MERCHANT_ID>" + actItem.merchantId + "</MERCHANT_ID>");
                    reqMsg.append("<PROTOCOL_REQ_SN>" + p_req.contractDetail.askNumber + "</PROTOCOL_REQ_SN>");
                    reqMsg.append("<VERIFY_CODE>" + p_req.contractDetail.smsCode + "</VERIFY_CODE>");
                    reqMsg.append("</TRANS_SUM>");
                    reqMsg.append("</BODY>");
                    reqMsg.append("</GZELINK>");
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
                    retAts.writeRetDetail(tmpRetDetail);
                    return retAts;
                }

                String signData = reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "");
                WriteBankLogLn2("签名原始数据:\r\n" + signData);

                String reqData = reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "<SIGNED_MSG>" + signMsg(signData, actItem) + "</SIGNED_MSG>");
                WriteBankLogStep2(reqData);

                String[] tmpRetStr = sendDataToGZE(reqData, bankFront.getUrl("contractSubmit"));

                if (tmpRetStr[0].length() == 0) {
                    WriteBankLogStep3(tmpRetStr[1]);

                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = tmpBkReader.getFirstText("/GZELINK/INFO/ERR_MSG");

                        String tmpRespCode = tmpBkReader.getFirstText("/GZELINK/INFO/RET_CODE");
                        if ("0000".equals(tmpRespCode)) {
                            String transStatus = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/TRANS_STATUS");
                            if ("01".equals(p_req.contractDetail.step)) {
                                tmpRetDetail.respInfo = StringHelper.joinNotEmpty("_", transStatus, tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/TRANS_INFO"));

                                String tmpProtocolNo = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/PROTOCOL_NO");
                                if ("3068".equals(transStatus) && StringHelper.hasAnyChar(tmpProtocolNo)) {
                                    tmpRetDetail.authCode = tmpProtocolNo;
                                }
                                tmpRetDetail.signConfirmType = this.getBankConfig().getMapValueByKey("signConfirmMapping", p_req.contractDetail.payBankCode);
                            } else {
                                if ("0000".equals(transStatus)) {
                                    tmpRetDetail.signState = ContractState.SUCCESS;
                                } else {
                                    tmpRetDetail.signState = ContractState.FAIL;
                                }
                                tmpRetDetail.authCode = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/PROTOCOL_NO");
                                String transInfo = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/TRANS_INFO");
                                ;
                                if (StringHelper.hasAnyChar(transInfo)) {
                                    tmpRetDetail.respInfo = transInfo;
                                }
                            }
                            tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", transStatus);
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/GZELINK/INFO/ERR_MSG");
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpRetStr[1];
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    @Override
    public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;

        try {
            String isSignbank = getBankConfig().getMapValueByKey("signbankMapping", p_reqQry.contractDetail.payBankCode);
            if ("1".equals(isSignbank)) {
                //广发 浦发查本地文件
                String tmpFileName = FGBiz.DSPHOME_Parent + File.separator + "signnotify";
                File tmpFile = new File(tmpFileName + File.separator + p_reqQry.contractDetail.payAct + ".txt");
                if (!tmpFile.exists()) {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "签约中";
                } else {
                    StringBuilder result = new StringBuilder();
                    BufferedReader br = null;
                    FileReader reader = null;
                    try {
                        reader = new FileReader(tmpFile);
                        br = new BufferedReader(reader);//构造一个BufferedReader类来读取文件
                        String s = null;
                        while ((s = br.readLine()) != null) {//使用readLine方法，一次读一行
                            result.append(File.separator + s);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (reader != null) {
                            reader.close();
                        }
                        if (br != null) {
                            br.close();
                        }
                    }
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(result.toString(), tmpSbMsg);
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReader.getFirstText("/RET_DETAIL/RespInfo");
                    tmpRetDetail.signState = ContractState.SUCCESS;
                    tmpRetDetail.authCode = tmpBkReader.getFirstText("/RET_DETAIL/AuthCode");
                    tmpRetDetail.payAct = tmpBkReader.getFirstText("/RET_DETAIL/PayAct");
                    tmpRetDetail.payName = tmpBkReader.getFirstText("/RET_DETAIL/PayName");
                    String cardType = tmpBkReader.getFirstText("/RET_DETAIL/ACCOUNT_TYPE");
                    if ("02".equals(cardType)) {
                        cardType = "3";
                    } else {
                        cardType = "2";
                    }
                    tmpRetDetail.cardType = cardType;
                    tmpRetDetail.certType = convertCertTypeToBank(tmpBkReader.getFirstText("/RET_DETAIL/CertType"));
                    tmpRetDetail.certNum = tmpBkReader.getFirstText("/RET_DETAIL/CertNum");
                    tmpRetDetail.cellPhone = tmpBkReader.getFirstText("/RET_DETAIL/CellPhone");
                    tmpRetDetail.legalName = tmpBkReader.getFirstText("/RET_DETAIL/LegalName");
                    tmpRetDetail.legalCertType = convertCertTypeToBank(tmpBkReader.getFirstText("/RET_DETAIL/LegalCertType"));
                    tmpRetDetail.legalCertNum = tmpBkReader.getFirstText("/RET_DETAIL/LegalCertNum");
                    tmpRetDetail.deadLine = tmpBkReader.getFirstText("/RET_DETAIL/DeadLine");
                    String singleLimit = tmpBkReader.getFirstText("/RET_DETAIL/SingleLimit");
                    if (StringHelper.hasAnyChar(singleLimit)) {
                        tmpRetDetail.singleLimit = StringHelper.amountDivide100(singleLimit);
                    }
                    String periodLimit = tmpBkReader.getFirstText("/RET_DETAIL/PeriodLimit");
                    if (StringHelper.hasAnyChar(periodLimit)) {
                        tmpRetDetail.periodLimit = periodLimit.substring(1);
                    }
                    tmpRetDetail.countLimit = tmpBkReader.getFirstText("/RET_DETAIL/CountLimit");
                }
            } else {
                ActSetItem actItem = getBankConfig().getActSetItem(p_reqQry.contractDetail.recAct, "contract");
                if (actItem != null) {
                    GZELINK01Header bankHeader = new GZELINK01Header();
                    bankHeader.transCode = "311004";
                    bankHeader.reqSeqNo = p_reqQry.reqHeader.transSeqID;

                    StringBuilder reqMsg = new StringBuilder();
                    reqMsg = writeCommonHeader(reqMsg, actItem, bankHeader);

                    reqMsg.append("<SUBMIT_TIME>" + Format.DateTime14Format.format(new Date()) + "</SUBMIT_TIME>");
                    reqMsg.append("<MERCHANT_ID>" + actItem.merchantId + "</MERCHANT_ID>");
                    reqMsg.append("<QUERY_MODE>4</QUERY_MODE>");
                    reqMsg.append("<PROTOCOL_REQ_SN></PROTOCOL_REQ_SN>");
                    reqMsg.append("<PROTOCOL_NO></PROTOCOL_NO>");
                    reqMsg.append("<ACCOUNT_NO>" + p_reqQry.contractDetail.payAct + "</ACCOUNT_NO>");
                    reqMsg.append("</TRANS_SUM>");
                    reqMsg.append("</BODY>");
                    reqMsg.append("</GZELINK>");

                    String signData = reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "");
                    WriteBankLogLn2("待签名数据:\r\n" + signData);

                    String signature = signMsg(signData, actItem);

                    String reqData = reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "<SIGNED_MSG>" + signature + "</SIGNED_MSG>");
                    WriteBankLogStep2(reqData);

                    String[] tmpRetStr = sendDataToGZE(reqData, bankFront.getUrl("contractSubmit"));
                    if (tmpRetStr[0].length() == 0) {
                        WriteBankLogStep3(tmpRetStr[1]);

                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);

                        if (tmpBkReader != null) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/GZELINK/INFO/ERR_MSG");

                            String tmpRespCode = tmpBkReader.getFirstText("/GZELINK/INFO/RET_CODE");
                            if ("0000".equals(tmpRespCode)) {
                                String tmpRespInfo = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/TRANS_INFO");
                                if (StringHelper.hasAnyChar(tmpRespInfo)) {
                                    tmpRetDetail.respInfo = tmpRespInfo;
                                }

                                // 0-已签约、1-已解约、2-未签约
                                String contractState = tmpBkReader.getFirstText("/GZELINK/BODY/RET_DETAILS/RET_DETAIL/SIGN_STATUS");
                                if ("0".equals(contractState)) {
                                    contractState = ContractState.SUCCESS;
                                } else {
                                    contractState = ContractState.UNSIGNED;
                                }
                                tmpRetDetail.signState = contractState;
                                tmpRetDetail.signConfirmType = this.getBankConfig().getMapValueByKey("signConfirmMapping", p_reqQry.contractDetail.payBankCode);
                                if (ContractState.SUCCESS.equals(tmpRetDetail.signState)) {
                                    if (tmpBkReader.read("/GZELINK/BODY/RET_DETAILS/RET_DETAIL")) {
                                        tmpRetDetail.authCode = tmpBkReader.readedXElement.getSingleText("PROTOCOL_NO");
                                        tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NO");
                                        tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NAME");
                                        String cardType = tmpBkReader.readedXElement.getSingleText("ACCOUNT_TYPE");
                                        if ("02".equals(cardType)) {
                                            cardType = "3";
                                        } else {
                                            cardType = "2";
                                        }
                                        tmpRetDetail.cardType = cardType;
                                        tmpRetDetail.certType = convertCertTypeToBank(tmpBkReader.readedXElement.getSingleText("ID_TYPE"));
                                        tmpRetDetail.certNum = tmpBkReader.readedXElement.getSingleText("ID");
                                        tmpRetDetail.cellPhone = tmpBkReader.readedXElement.getSingleText("TEL");
                                        tmpRetDetail.legalName = tmpBkReader.readedXElement.getSingleText("LGL_REP_NM");
                                        tmpRetDetail.legalCertType = convertCertTypeToBank(tmpBkReader.readedXElement.getSingleText("LGL_REP_ID_TP"));
                                        tmpRetDetail.legalCertNum = tmpBkReader.readedXElement.getSingleText("LGL_REP_ID_NO");
                                        tmpRetDetail.deadLine = tmpBkReader.readedXElement.getSingleText("DISABLE_DATE");
                                        String singleLimit = tmpBkReader.readedXElement.getSingleText("SINGLE_LIMIT");
                                        if (StringHelper.hasAnyChar(singleLimit)) {
                                            tmpRetDetail.singleLimit = StringHelper.amountDivide100(singleLimit);
                                        }
                                        String periodLimit = tmpBkReader.readedXElement.getSingleText("LIMIT_PERIOD_UNIT");
                                        if (StringHelper.hasAnyChar(periodLimit)) {
                                            tmpRetDetail.periodLimit = periodLimit.substring(1);
                                        }
                                        tmpRetDetail.countLimit = tmpBkReader.readedXElement.getSingleText("MAX_CNT_LIMIT");
                                        tmpRetDetail.cellPhone = tmpBkReader.readedXElement.getSingleText("TEL");
                                    }
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = tmpBkReader.getFirstText("/GZELINK/INFO/ERR_MSG");
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpRetStr[1];
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "未找到账号:[" + p_reqQry.contractDetail.recAct + "]商户配置信息!";
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        return null;
    }
}
